package itsm.isperp.workflow.engine.diagram;

import java.awt.Color;
import java.awt.Font;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.RoundRectangle2D;
import java.util.List;

import org.activiti.bpmn.model.AssociationDirection;
import org.activiti.bpmn.model.GraphicInfo;
import org.activiti.image.impl.DefaultProcessDiagramCanvas;
import org.apache.commons.lang3.StringUtils;

/**
 * 
 * 自定义流程图形画布,集成与{@link ProcessDiagramCanvas} ,重新部分节点一边写出文字,增加
 * {@link drawSequenceflowText} 方法用于画连接线上的文字
 * 
 * @author lizx
 * @date 2013-7-8
 * 
 */
public class CustomerProcessDiagramCanvas extends DefaultProcessDiagramCanvas {

	public CustomerProcessDiagramCanvas(int width, int height, int minX,
			int minY, String imageType, String activityFontName,
			String labelFontName, ClassLoader customClassLoader) {

		super(width, height, minX, minY, imageType, activityFontName,
				labelFontName, customClassLoader);
		HIGHLIGHT_COLOR = new Color(21, 162, 48);

	}

	public CustomerProcessDiagramCanvas(int width, int height, int minX,
			int minY, String imageType) {
		super(width, height, minX, minY, imageType);
		HIGHLIGHT_COLOR = new Color(21, 162, 48);

	}

	@Override
	public void initialize(String imageType) {

		Font font = new Font(activityFontName, Font.BOLD, FONT_SIZE);
		if (g != null) {
			g.setFont(font);
			this.fontMetrics = g.getFontMetrics();
		}
		LABEL_FONT = new Font(labelFontName, Font.ITALIC, FONT_SIZE);

		ANNOTATION_FONT = new Font(labelFontName, Font.PLAIN, FONT_SIZE);
		TASK_FONT = new Font(labelFontName, Font.PLAIN, FONT_SIZE);
		super.initialize(imageType);
	}

	/**
	 * 画出连接线的文字
	 * 
	 * @param name
	 *            文本
	 * @param waypoints
	 *            连接线坐标(共四个)
	 */
	public void drawSequenceflowText(String name, List<Integer> waypoints) {
		if (StringUtils.isNotEmpty(name))
			g.drawString(name, waypoints.get(0).intValue(),
					(waypoints.get(0) + waypoints.get(1)) / 2);
	}

	public void drawSequenceflow(String name, int[] xPoints, int[] yPoints,
			boolean conditional, boolean isDefault, boolean highLighted,
			double scaleFactor) {
		drawConnection(xPoints, yPoints, conditional, isDefault,
				"sequenceFlow", AssociationDirection.ONE, highLighted,
				scaleFactor);

		// if (StringUtils.isNotEmpty(name)) {
		// int x = 0;
		// int y = 0;
		//
		// if (xPoints[0] < xPoints[1] && yPoints[0] == yPoints[1]) {
		// // 东
		// x = xPoints[0] + 5;
		// y = (yPoints[0] + yPoints[1]) / 2;
		// } else {
		// x = (xPoints[0] + xPoints[1]) / 2;
		// y = (yPoints[0] + yPoints[1]) / 2;
		// }
		//
		// g.drawString(name, x, y);
		// }

	}

	public void drawSequenceflowWithoutArrow(String name, int srcX, int srcY,
			int targetX, int targetY, boolean conditional, double scaleFactor) {

		drawSequenceflowWithoutArrow(srcX, srcY, targetX, targetY, conditional,
				false, scaleFactor);
		if (StringUtils.isNotEmpty(name))
			this.g.drawString(name, srcX, srcY);

	}

	public void drawSequenceflow(String name, int srcX, int srcY, int targetX,
			int targetY, boolean conditional, double scaleFactor) {
		drawSequenceflow(srcX, srcY, targetX, targetY, conditional, false,
				scaleFactor);

		if (StringUtils.isNotEmpty(name))
			this.g.drawString(name, srcX, srcY);

	}

	public void drawNoneStartEvent(String name, GraphicInfo graphicInfo) {

		drawStartEvent(graphicInfo, null, 1.0);
		if (name != null) {

			int textX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() - this.fontMetrics
					.stringWidth(name)) / 2);
			int textY = (int) (graphicInfo.getY()
					+ (graphicInfo.getHeight() - this.fontMetrics.getHeight() / 2)
					/ 2 + this.fontMetrics.getHeight() / 2);
			this.g.drawString(name, textX, textY);

		}

	}

	public void drawNoneEndEvent(String name, GraphicInfo graphicInfo,
			double scaleFactor) {

		drawNoneEndEvent(graphicInfo, scaleFactor);

		if (name != null) {

			int textX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() - this.fontMetrics
					.stringWidth(name)) / 2);
			int textY = (int) (graphicInfo.getY()
					+ (graphicInfo.getHeight() - this.fontMetrics.getHeight() / 2)
					/ 2 + this.fontMetrics.getHeight() / 2);
			this.g.drawString(name, textX, textY);

		}

	}

	public void drawExclusiveGateway(String name, GraphicInfo graphicInfo,
			double scaleFactor) {
		this.drawExclusiveGateway(graphicInfo, scaleFactor);
		if (name != null) {
			int textX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() - this.fontMetrics
					.stringWidth(name)) / 2);
			int textY = (int) (graphicInfo.getY()
					+ (graphicInfo.getHeight() - this.fontMetrics.getHeight())
					+ this.fontMetrics.getHeight() + 10);
			this.g.drawString(name, textX, textY);

		}

	}

	public void drawInclusiveGateway(String name, GraphicInfo graphicInfo,
			double scaleFactor) {
		this.drawInclusiveGateway(graphicInfo, scaleFactor);
		if (name != null) {
			int textX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() - this.fontMetrics
					.stringWidth(name)) / 2);
			int textY = (int) (graphicInfo.getY()
					+ (graphicInfo.getHeight() - this.fontMetrics.getHeight())
					/ 2 + this.fontMetrics.getHeight());
			this.g.drawString(name, textX, textY);

		}

	}

	public void drawParallelGateway(String name, GraphicInfo graphicInfo,
			double scaleFactor) {
		this.drawParallelGateway(graphicInfo, scaleFactor);
		if (name != null) {
			int textX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() - this.fontMetrics
					.stringWidth(name)) / 2);
			int textY = (int) (graphicInfo.getY()
					+ (graphicInfo.getHeight() - this.fontMetrics.getHeight())
					/ 2 + this.fontMetrics.getHeight());
			this.g.drawString(name, textX, textY);

		}
	}

	public void drawHighLight(int x, int y, int width, int height, int arc) {
		Paint originalPaint = g.getPaint();
		Stroke originalStroke = g.getStroke();

		g.setPaint(HIGHLIGHT_COLOR);
		g.setStroke(THICK_TASK_BORDER_STROKE);

		RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
				height, arc, arc);
		g.draw(rect);

		g.setPaint(originalPaint);
		g.setStroke(originalStroke);
	}

	public void drawHighLightBlue(int x, int y, int width, int height, int arc) {
		Paint originalPaint = g.getPaint();
		Stroke originalStroke = g.getStroke();

		g.setPaint(Color.RED);
		g.setStroke(THICK_TASK_BORDER_STROKE);

		RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
				height, arc, arc);
		g.draw(rect);

		g.setPaint(originalPaint);
		g.setStroke(originalStroke);
	}
}
